package org.nhindirect.stagent;

import java.util.ArrayList;
import java.util.Collection;
import javax.mail.internet.InternetAddress;

import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerInformation;
import org.nhindirect.stagent.trust.TrustEnforcementStatus;


public class IncomingMessage extends NHINDMessage
{
	
	CMSSignedData m_signature;
    SignerInformation m_signer;
    NHINDAddressCollection m_domainRecipients;
    Collection<InternetAddress> m_otherRecipients;        
    NHINDAddressCollection m_rejectedRecipients;
    
    public IncomingMessage()
    {
    }

    public IncomingMessage(MimeEntity entity)
    {
    	this.setHeaders(entity.getHeaders());
    	this.setBody(entity.getBody());
    }        
    
    @Override
    public Header getTo()
    {
    	return super.getTo();
    }
    
    public void setTo(Header value)
    {
       super.setTo(value);
       this.m_domainRecipients = null;
       this.m_otherRecipients = null;

    }

    public NHINDAddressCollection getDomainRecipients()
    {

        if (this.m_domainRecipients == null)
        {
            this.categorizeRecipients(this.getAgent().getDomain());
        }

        return this.m_domainRecipients;
    }

    public boolean hasDomainRecipients()
    {

        NHINDAddressCollection recipients = this.getDomainRecipients();
        return (recipients != null && recipients.size() > 0);
    }

    public Collection<InternetAddress> getOtherRecipients()
    {
        if (this.m_otherRecipients == null)
        {
            this.categorizeRecipients(this.getAgent().getDomain());
        }
        
        return this.m_otherRecipients;        
    }

    public boolean hasOtherRecipients()
    {

    	Collection<InternetAddress> recipients = this.getOtherRecipients();
            
    	return (recipients != null && recipients.size() > 0);
    }

    public NHINDAddressCollection getRejectedRecipients()
    {

        if (this.m_rejectedRecipients == null)
        {
            this.m_rejectedRecipients = new NHINDAddressCollection();
        }

        return this.m_rejectedRecipients;
    }

    public boolean hasRejectedRecipients()
    {
        return (this.m_rejectedRecipients != null && this.m_rejectedRecipients.size() > 0);
    }
            
    public CMSSignedData getSignature()
    {
        return this.m_signature;
    }
            
    public void setSignature(CMSSignedData value)
    {
        this.m_signature = value;
    }

    public SignerInformation getValidatedSigner()
    {
        return this.m_signer;
    }
    
    public void setValidatedSigner(SignerInformation value)
    {
        this.m_signer = value;
    }

    public boolean isSignatureVerified()
    {
        return (this.m_signer != null);
    }

    /// <summary>
    /// Split "To" into recipients who are in this domain vs external
    /// </summary>
    /// <param name="domain"></param>
    void categorizeRecipients(String domain)
    {
        if (domain == null || domain.length() == 0)
        {
            throw new IllegalArgumentException();
        }
        
        Collection<InternetAddress> to = this.getParsedTo();

        this.m_domainRecipients = new NHINDAddressCollection();
        this.m_otherRecipients = new ArrayList<InternetAddress>();
        
        for (InternetAddress address : to)
        {
            if (address.getAddress().contains(domain))
            {
                this.m_domainRecipients.add(new NHINDAddress(address));
            }
            else
            {
                this.m_otherRecipients.add(address);
            }
        }
    }

    void categorizeRecipients(TrustEnforcementStatus minTrustStatus)
    {
        this.m_rejectedRecipients = NHINDAddressCollection.create(this.getDomainRecipients().getUntrusted(minTrustStatus));
        this.getDomainRecipients().removeUntrusted(minTrustStatus);
        
    }

    /// <summary>
    /// Combine the valid domain recipients & other recipients into a "To"
    /// </summary>
    void updateTo()
    {
        Collection<InternetAddress> recipients = this.getDomainRecipients().toInternetAddressCollection();
        recipients.addAll(this.getOtherRecipients());
        
        this.setParsedTo(recipients);
    }

}
